﻿#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QApplication>
#include <QFile>
#include <QTextCodec>
#include <QFontDatabase>
#include <QFont>
#include "QThread"
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QVariant>
#include <QSqlRecord>
#include "execonfig.h"
#include <QQmlContext>
#include <CommunicationMethod.h>
#include "reportInterface.h"
#include "reportManager.h"
#include <DbHelper.h>
#include <GetMessageInterface.h>
#include <SpeechModuleThread.h>
#include "animationManager.h"
#include "camera/cameraProvider.h"
#include "printerManager.h"
#include "defaultset.h"
#include "licenseManager/licenseManager.h"
#include <StatMaint.h>
#include "MaintenanceAndCorrection.h"
#include "chromatogram/chromatogramChart.h"
#include "chromatogram/chromatogramManager.h"
#include "barCodeManager.h"
#include <QTranslator>
#include "qmllanguage.h"
#include "QQuickWindow"
#include "updateExe.h"
#include <Thread/DataSerialportClient.h>

//全局变量
QMap<int,QVariantMap> expLogInfo;//实验日志, QVariantMap Step 步骤 FinishTime 时间 actionInfo动作信息 status 状态(未执行,完成,异常);
QString currentStep;  //当前执行中实验步骤
speechModuleThread *spmoduleth;    //语音模块
QMap<int,QVariantMap> expSendList; //发送列表
int expStatus;//实验状态 0空闲 1实验中 2暂停
int expStep;//发送解析完实验步骤
QString expName;//选中的实验名称
QString expConsumablesType;//耗材类型
double totalExpTime;//当前实验需要的总时间
QString stepOperatingInfo;
bool haveConsumables;
bool heartMsg;
QVector<double> cpsPartData;
bool isProductTesting =false;//产物检测
QString dataThresholdType;
double dataThreshold;
int  productSyringStep;//产物注射器步骤
QDateTime productSyringStartTime;
bool firstConnect;

void onTimeout() {
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);
    QDateTime current=QDateTime::currentDateTime();
    QString dateStr=current.toString("yyyy-MM-dd");
    QString sql=QString("Select count(*) Num From DataStatistics Where StaticDate='%1'").arg(dateStr);
    query.exec(sql);
    int num;
    while (query.next()) {
        num=query.value("Num").toInt();
    }
    if(num>0){
        sql=QString("Update DataStatistics Set EquOperatingTime=(EquOperatingTime*3600.0+60)/3600.0 Where StaticDate='%1'").arg(dateStr);
        query.exec(sql);
    }else{
        sql=QString("Insert into DataStatistics Values('%1','0','0','0','0','0')").arg(dateStr);
        query.exec(sql);
        sql=QString("Update DataStatistics Set EquOperatingTime=(EquOperatingTime*3600.0+60)/3600.0 Where StaticDate='%1'").arg(dateStr);
        query.exec(sql);
    }

}

void onHeartTimeout(){
//    UdpClient *udpClient;
//    udpClient=UdpClient::getInstance();

//    if(udpClient->IsOnline())
//    {
//        CommonHelper *common =CommonHelper::commonInstance();
//        QString info =CommCommand::I().connectToLc();
//        udpClient->ClientSendingData(common->GetSendData(info));
//        heartMsg=false;
//    }
//    else
//    {
//        QMLSignal::I().emitCommunicationStatus(1);     // 发信号通知前端
//    }

}

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    //解决窗口拖拽时闪烁的问题
    QCoreApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
    //    QQuickWindow::setSceneGraphBackend(QSGRendererInterface::OpenGLRhi);

    //    QGuiApplication app(argc, argv);
    QApplication app(argc, argv);

    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
    QGuiApplication::setAttribute(Qt::AA_UseDesktopOpenGL, true);
    QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling, false);


    int fontId = QFontDatabase::addApplicationFont(":/fonts/AlibabaPuHuiTi-3-55-Regular.ttf");      // 字体设置
    if(fontId != -1){
        QStringList fontFamilies = QFontDatabase::applicationFontFamilies(fontId);
        if(fontFamilies.isEmpty()){
            qDebug("设置字体失败2");
        }
        QString familyName = fontFamilies.first();
        QFont font(familyName, 10);
        app.setFont(font);
    }else{
        qDebug("设置字体失败");
    }
    QQmlApplicationEngine engine;

    //切换为本地语言
    //检测本系统语言自动装载翻译文件
    //使用qt的QLocale这个类，通过这个类来获取系统本地语言环境
    //QTranslator的load方法装载语言包
    //QGuiApplication的实例化对象的installTranslator去实现语言翻译
    QTranslator translator;
    QLocale locale;
    if( locale.language() == QLocale::English ) {
        translator.load(":/en_us.qm");
    }
    else if( locale.language() == QLocale::Chinese ) {
        translator.load(":/zh_CN.qm");
    }
    app.installTranslator(&translator);

    //将QmlLanguage中的所有函数暴露给qml调用
    QmlLanguage qmlLanguage(app, engine);
    engine.rootContext()->setContextProperty("qmlLanguage", &qmlLanguage);


    const QUrl url(QStringLiteral("qrc:/main.qml"));
    QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                     &app, [url](QObject *obj, const QUrl &objUrl) {
        if (!obj && url == objUrl)
            QCoreApplication::exit(-1);
    }, Qt::QueuedConnection);
    engine.load(url);

    //创建数据库
    QSqlDatabase db = dbHelper::openConnection();
    QSqlQuery query(db);

    db.transaction();
    QFile file(":/file/dbInfo.txt");
    QTextCodec* codec = QTextCodec::codecForName("GBK");
    file.open(QIODevice::ReadOnly | QIODevice::Text);

    QTextStream txtInput(&file);
    txtInput.setCodec(codec);
    while (!txtInput.atEnd())
    {
        QString lineStr = txtInput.readLine();
        query.exec(lineStr);
    }

    db.commit();


    ExeConfig *execonf = new ExeConfig();
    engine.rootContext()->setContextProperty("CExeConfig", execonf);

    DefaultSet *defaults = new DefaultSet();
    engine.rootContext()->setContextProperty("CDefaultS",defaults);

    CommunicationMethod *comMethod = new CommunicationMethod();
    engine.rootContext()->setContextProperty("CommunicationMethod", comMethod);

    ReportInterface* reportInterface = new ReportInterface();
    engine.rootContext()->setContextProperty("CReport", reportInterface);


    StatMaint* statMaint = new StatMaint();
    engine.rootContext()->setContextProperty("CStatMaint", statMaint);

    ChromatogramChart* chromChart = new ChromatogramChart();
    ChromatogramManager* chromManager = new ChromatogramManager();
    chromManager->_chart = chromChart;
    engine.rootContext()->setContextProperty("CChromChart", chromChart);
    engine.rootContext()->setContextProperty("CChromManager", chromManager);

    MaintenanceAndCorrection* Maintenance = new MaintenanceAndCorrection();
    engine.rootContext()->setContextProperty("CMaintenance", Maintenance);

    //    AnimationState* animationS = new AnimationState();
    //    engine.rootContext()->setContextProperty("CAnimation", animationS);

    //    AnimationController* animationC = new AnimationController(animationS);
    //    engine.rootContext()->setContextProperty("CAnimationPrinter", animationC);

    GetMessageInterface *getMessageInterface=new GetMessageInterface();
    engine.rootContext()->setContextProperty("GetMessageInterface", getMessageInterface);

    chromManager->_msgInterface = getMessageInterface;      // 给能谱图后端提供接口

    BarCodeManager *barCode = new BarCodeManager();
    engine.rootContext()->setContextProperty("CBarCode", barCode);

    UpdateExe* exeUpdater = new UpdateExe();
    engine.rootContext()->setContextProperty("CExeUpdater", exeUpdater);


    engine.rootContext()->setContextProperty("CSignal", &(QMLSignal::I()));
    engine.rootContext()->setContextProperty("CReportManager", &(ReportManager::I()));
    engine.rootContext()->setContextProperty("CAnimation", &(AnimationManager::I()));
    engine.rootContext()->setContextProperty("CPrinter", &(PrinterManager::I()));       // 打印机
    engine.rootContext()->setContextProperty("CLicense", &(LicenseManager::I()));       //
    PrinterManager::I().initProvider(&engine);
    QMLSignal::I().emitCommunicationStatus(1);     // 发信号通知前端
    spmoduleth = new speechModuleThread();
    // 启动摄像头
    CameraProvider* cameraProvider = new CameraProvider(&engine);
    engine.rootContext()->setContextProperty("CCamera", cameraProvider);
    cameraProvider->startCamera();
    if(cameraProvider->isConnected){
        cameraProvider->start();
    }

    QTimer timer;
    // 连接定时器的 timeout 信号到槽函数 onTimeout
    QObject::connect(&timer, &QTimer::timeout, &onTimeout);
    // 启动定时器，每隔 1000 毫秒触发一次
    timer.start(60000);

    firstConnect=true;

    QString ip,port;
    QString sql="Select Ip,Port From IpInfo Where ConnectType='0'";
    query.exec(sql);
    while (query.next()) {
        ip=query.value("Ip").toString();
        port=query.value("Port").toString();
    }
    CommonHelper *common =CommonHelper::commonInstance();
    UdpClient *udpClient= UdpClient::getInstance();
    udpClient->ClientConnectToHost(ip, port.toInt());
    QString sendInfo=CommCommand::I().connectToLc();
    udpClient->ClientSendingData(common->GetSendData(sendInfo));

    QTimer heartTimer;
    QObject::connect(&heartTimer, &QTimer::timeout, &onHeartTimeout);
    // 启动定时器，每隔5秒触发一次
    heartTimer.start(5000);

    DataSerialportClient *serialPortClient;
    serialPortClient=new DataSerialportClient();
    serialPortClient->startAutoSend(2000,"COM4");


    return app.exec();
}
